﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.IO;
using System.ComponentModel;
using System.Collections.ObjectModel;
using baselib;
using System.Net;

namespace AutoUpdateConfig
{
    /// <summary>
    /// 很简单的功能，就不用MVVM了
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            dgs.ItemsSource = NeedUpdateFiles;
            LogHelper.WriteDebug("MainWindow Open Success");
        }

        public ObservableCollection<NeddUpdateFile> NeedUpdateFiles = new ObservableCollection<NeddUpdateFile>();

        const string UpdateConfigFile = "UpdateConfigFile.json";

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
            dialog.Description = "请选择待上传程序所在文件夹";
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtFolder.Text = dialog.SelectedPath;

            }
        }


        
        /// <summary>
        /// 递归获取文件夹下的所有文件的绝对路径
        /// </summary>
        private void GetDirectoryFiles(string folderpath, List<string> absolutefiles)
        {
            var folders = Directory.GetDirectories(folderpath);
            foreach(var folder in folders)
            {
                if (folderpath+"\\AutoUpdate" == folder)
                    continue;
                GetDirectoryFiles(folder, absolutefiles);
            }


            var files = Directory.GetFiles(folderpath);
            foreach(var file in files)
            {
                absolutefiles.Add(file);
            }
        }


        /// <summary>
        /// 下载服务器对应UniqueName的UpdateConfigFile.json的内容，
        /// </summary>
        /// <param name="url"></param>
        /// <param name="UniqueName"></param>
        public bool DownLoadUpdateConfig(string url, string UniqueName)
        {
            url = $"{url}/file/getversion/{UniqueName}";

            Encoding encoding = Encoding.UTF8;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "Get";

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode == HttpStatusCode.OK)
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    StreamReader reader = new StreamReader(responseStream);
                    var json = reader.ReadToEnd();

                    try
                    {
                        if (string.IsNullOrWhiteSpace(json))
                            return false;
                        tv = Newtonsoft.Json.JsonConvert.DeserializeObject<TotalFileVersion>(json);
                        return true;
                    }
                    catch (Exception)
                    {

                        //MessageBox.Show("下载UpdateConfigFile.json信息失败");
                        return false;
                    }

                }
            }
            return false;
        }



        private TotalFileVersion tv;
        string UpdateConfigFilePath = string.Empty;
        private void ButtonScanClick(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(versonName.Text))
            {
                MessageBox.Show("请输入一个唯一的版本名称");
                return;
            }
            string folderpath = txtFolder.Text;
            if (!Directory.Exists(folderpath))
                return;

            bool isNew = true;

            UpdateConfigFilePath = folderpath + @"\" + UpdateConfigFile;

            //此处逻辑有问题，不应该是检测本地，二十应该去检测服务器上的updateconfigfile.json文件
            //if (File.Exists(UpdateConfigFilePath))
            //{
            //    isNew = false;
            //}

            if(DownLoadUpdateConfig(txtserver.Text, versonName.Text))
            {
                isNew = false;
            }


            List<string> files = new List<string>();
            GetDirectoryFiles(folderpath, files);



            NeedUpdateFiles.Clear();


            if (isNew==true)//首次创建则需新建文件
            {
                tv = new TotalFileVersion() { TotalVersion =1};

                foreach (string filename in files)
                {
                    FileInfo info = new FileInfo(filename);
                    string relitivepath = PathHelper.GetRelitivePath(filename, folderpath);
                    FileUnit fileUnit= new FileUnit(relitivepath, 1, (int)info.Length, info.LastWriteTime);
                    tv.FileUnits.Add(fileUnit);
                    NeedUpdateFiles.Add(new NeddUpdateFile(filename, relitivepath, fileUnit));
                }

            }
            else //非首次，则拿本地UpdateConfigFile.json中的内容和实际每个文件的信息做比较
            {
                //using (FileStream totalFileVersionFile = new FileStream(UpdateConfigFilePath, FileMode.Open))
                {
                    //using(StreamReader rd= new StreamReader(totalFileVersionFile) )
                    {
                        //string json = rd.ReadToEnd();
                        //tv= Newtonsoft.Json.JsonConvert.DeserializeObject<TotalFileVersion>(json);
                        versonName.Text = tv.UniqueName;
                        foreach (string filename in files)
                        {
                            var fileshortname = PathHelper.GetRelitivePath(filename, folderpath);
                            if (fileshortname== UpdateConfigFile)
                            {
                                continue;
                            }

                            FileInfo info = new FileInfo(filename);
                            FileUnit fileUnit = new FileUnit(fileshortname, 1, (int)info.Length, info.LastWriteTime);

                            //删除先不管
                            //{ 
                            //}
                            
                            var fileUnitInTV= tv.FileUnits.FirstOrDefault((file) => { return file.FileRelativePath == fileshortname; });
                            
                            //如果tv中不存在，则为新增的文件
                            if (fileUnitInTV==null)
                            {
                                //tv.FileUnits.Add(fileUnit);
                                NeedUpdateFiles.Add(new NeddUpdateFile(filename, fileshortname, fileUnit));
                            }
                            else//tv中存在，则比较，若不一样则需要跟新
                            {
                                if(fileUnitInTV.FileSize != fileUnit.FileSize || fileUnitInTV.LastUpdateTime != fileUnit.LastUpdateTime)
                                {
                                    //fileUnitInTV.FileSize = fileUnit.FileSize;
                                    //fileUnitInTV.LastUpdateTime = fileUnit.LastUpdateTime;
                                    //fileUnitInTV.Version += 1;//版本+1
                                    NeedUpdateFiles.Add(new NeddUpdateFile(filename, fileshortname, fileUnit));
                                }
                            }
                        }
                    }

                }
            }
            if (NeedUpdateFiles.Count == 0)
                MessageBox.Show("扫描完成，没有发现需要跟新的文件");
            //NeedUpdateFiles.Add(new NeddUpdateFile(UpdateConfigFilePath, UpdateConfigFile));

            //else
                //MessageBox.Show("扫描完成，没有发现需要跟新的文件");



        }


        private async void ButtonUploadClick(object sender, RoutedEventArgs e)
        {
            if(NeedUpdateFiles.Count(a=> { return a.IsChecked == true; })==0)
            {
                MessageBox.Show("请先点击自动扫描生成待更新文件列表");
                return;
            }

            string url = txtserver.Text + "/file/UploadFile";
            var UniqueName = versonName.Text;



            //上传所有文件到服务器

            foreach (var item in NeedUpdateFiles.Where(f=> { return f.IsChecked == true; }))
            {
                Dispatcher.Invoke(() =>
                {
                    uploadfilename.Content = Path.GetFileName(item.FileName);
                });
                string ret =await UploadFile(url, item.FileName, UniqueName,item.RelitiveFilePath);

                Dispatcher.Invoke(() =>
                {
                    item.Status = "已更新";

                });

                var fileunit=tv.FileUnits.FirstOrDefault(a => { return a.FileRelativePath == item.RelitiveFilePath; });
                //存在则替换
                if (fileunit == null)
                    tv.FileUnits.Add(item.fileUnit);
                else
                {
                    fileunit.FileSize = item.fileUnit.FileSize;
                    fileunit.LastUpdateTime = item.fileUnit.LastUpdateTime;
                    fileunit.Version += 1;//版本+1
                }
            }


            //生成总版本json文件
            tv.UniqueName = UniqueName;
            tv.TotalVersion += 1;
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(tv);
            byte[] btBodys = Encoding.UTF8.GetBytes(json);
            using (FileStream totalFileVersionFile = new FileStream(UpdateConfigFilePath, FileMode.Create))
            {
                totalFileVersionFile.Write(btBodys, 0, btBodys.Length);

            }
            //上传UpdateConfigFile.json
            await UploadFile(url, UpdateConfigFilePath, UniqueName,UpdateConfigFile);

            Dispatcher.Invoke(() =>
            {
                MessageBox.Show("全部跟新完毕");
                uploadfilename.Content = "";
                Window_Loaded(null,null);
            });

        

        }

        public  void UploadProgress(object sender, UploadProgressChangedEventArgs e)
        {
            Dispatcher.Invoke(() =>
            {
                downPercent.Value = e.ProgressPercentage;
            });
            
        }


        public async Task<string> UploadFile(string url, string filepath, string UniqueName, string RelitivePath)
        {
            try
            {
                if (!File.Exists(filepath))
                {
                    MessageBox.Show("没找到文件" + filepath);
                    return "";
                }
                WebClient webClient = new WebClient();
                webClient.Credentials = CredentialCache.DefaultCredentials;
                webClient.Headers.Add("Content-Type", "application/form-data");//注意头部必须是form-data
                webClient.QueryString["UniqueName"] = UniqueName;
                webClient.QueryString["RelitivePath"] = RelitivePath;
                webClient.UploadProgressChanged += UploadProgress;
                byte[] fileb = await webClient.UploadFileTaskAsync(url, "Post", filepath);
                string response = Encoding.UTF8.GetString(fileb);
                return response;
            }
            catch (Exception e)
            {
                
                MessageBox.Show(e.Message);
                return "";
            }

        }

        private async void Window_Loaded(object sender, RoutedEventArgs e)
        {
            string url = txtserver.Text + "/file/getversions";
            List<string> ss = new List<string>();
            await Task.Run(()=> {
                string ret = WebapiHelp.HttpGetRequest(url);
                ss = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(ret);
            });

            lstbox.ItemsSource = ss;
        }

        private  void txtserver_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
        {
            if(lstbox!=null)
                Window_Loaded(null, null);
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            string url = txtserver.Text + "/file/CheckNeedUpload";
            string folderpath = txtFolder.Text;
            if (!Directory.Exists(folderpath))
                return;
            if (string.IsNullOrWhiteSpace(versonName.Text))
            {
                MessageBox.Show("请输入一个唯一的版本名称");
                return;
            }
            var UniqueName = versonName.Text;
            TotalFileVersion tvlocal = new TotalFileVersion() { TotalVersion = 0,UniqueName= UniqueName };


            //var files = Directory.GetFiles(folderpath);   
            List<string> files = new List<string>();
            GetDirectoryFiles(folderpath, files);
            foreach (string filename in files)
            {
                FileInfo info = new FileInfo(filename);
               
                FileUnit fileUnit = new FileUnit(filename, 1, (int)info.Length, info.LastWriteTime);
                tvlocal.FileUnits.Add(fileUnit);
            }
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(tvlocal);
            Console.WriteLine(json);
            string ret = WebapiHelp.CheckNeedUpload(url,json);

            Console.WriteLine(ret);
        }

        private void lstbox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            if(lstbox.SelectedItem!=null)
            {
                versonName.Text = lstbox.SelectedItem.ToString();
            }
        }
    }




}
